<?php
/** */
namespace app\api\service;

use Exception;
use app\api\model\Order as OrderModel;
use app\api\service\Order as OrderService;
use app\lib\enum\OrderStatusEnum;
use app\lib\exception\OrderException;
use app\lib\exception\TokenException;
use think\Loader;
use think\Log;

//子文件夹.文件，路径,后缀
Loader::import('WxPay.WxPay',EXTEND_PATH,'.Api.php');

class Pay{
    private $orderID;
    private $orderNo;

    function __construct($orderID){
        if (!$orderID) {
            throw new Exception('订单号不允许为NULL');
        }
        $this->orderID=$orderID;
    }

    public function pay(){
        //订单号可能根本不存在
        //订单号存在，和当前用户不匹配
        //订单已经被支付
        //进行库存量检测
        $this->checkOrderValid();
        $orderService=new OrderService();//引用
        $status=$orderService->checkOrderStock($this->orderID);//库存量检查
        if(!$status['pass']){
            return $status;
        }
        return $this->makeWxPreOrder($status['orderPrice']);
    }

    //微信预订单生成
    private function makeWxPreOrder($totalPrice){
        $openid=Token::getCurrentTokenVar('openid');
        if(!$openid){
            throw new TokenException();
        }
        $wxOrderData=new \WxPayUnifiedOrder();//统一下单的对象
        $wxOrderData->SetOut_trade_no($this->orderNo);//订单号
        $wxOrderData->SetTrade_type('JSAPI');//交易类型
        $wxOrderData->SetTotal_fee($totalPrice*100);//订单总价
        $wxOrderData->SetBody('商城');//商品简要描述
        $wxOrderData->SetOpenid($openid);//身份标识
        $wxOrderData->SetNotify_url(config('secure.pay_back_url'));//url地址接收微信回调通知(接口)

        return $this->getPaySignature($wxOrderData);
    }

    //把wxOrderData对象发送到微信的预订单接口，返回签名参数结果
    private function getPaySignature($wxOrderData){

        $config=new \WxPayConfig();
        $wxOrder=\WxPayApi::unifiedOrder($config,$wxOrderData);

        if ($wxOrder['return_code']!= 'SUCCESS' ||
             $wxOrder['return_code']!='SUCCESS') 
        {
            Log::record($wxOrder,'error');
            Log::record('获取预支付订单失败','error');
        }
        //1、保存prepay_id以备后期发送模板消息给用户
        $this->recordPreOrder($wxOrder);

        //2、对$wxOrder的数据进行加工
        $signatrue=$this->sign($wxOrder);

        return $signatrue;
    }

    //签名
    private function sign($wxOrder){
        $jsApiPayData=new \WxPayJsApiPay();
        $jsApiPayData->SetAppid(config('wx.app_id'));
        $jsApiPayData->SetTimeStamp((string)time());

        $rand=md5(time().mt_rand(0,1000));
        $jsApiPayData->SetNonceStr($rand);

        $jsApiPayData->SetPackage('prepay_id='.$wxOrder['prepay_id']);
        $jsApiPayData->SetSignType('md5');

        $config=new \WxPayConfig();
        $sign=$jsApiPayData->MakeSign($config);//生成签名
        $rawValues=$jsApiPayData->GetValues();
        $rawValues['paySign']=$sign;

        unset($rawValues['appId']);

        return $rawValues;
    }

    //处理prepay_id保存到数据库,做更新处理
    private function recordPreOrder($wxOrder){
        OrderModel::where('id','=',$this->orderID)
            ->update(['prepay_id'=>$wxOrder['prepay_id']]);
    }

    //订单存在检查
    private function checkOrderValid(){
        $order=OrderModel::where('id','=',$this->orderID)
            ->find();
        if(!$order){
            throw new OrderException();
        }
        if (!Token::isValidOperate($order->user_id)) {
            throw new TokenException([
                'msg'=>'订单与用户不匹配',
                'errorCode'=>10003
            ]);
        }
        if($order->status!=OrderStatusEnum::UNPAID){
            throw new OrderException([
                'msg'=>'订单已支付过啦',
                'errorCode'=>80003,
                'code'=>400
            ]);
        }
        $this->orderNO=$order->order_no;
        
        return true;
    }
        
}